package com.leo.customer.config

import com.alibaba.fastjson.JSON
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.auth0.jwt.exceptions.JWTDecodeException
import com.auth0.jwt.exceptions.JWTVerificationException
import com.leo.annotation.PassToken
import com.leo.annotation.UserLoginToken
import com.leo.customer.Constants
import com.leo.customer.entity.dao.UserDao
import com.leo.customer.entity.pojo.UserVo
import com.leo.customer.manager.RedisManager
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.util.StringUtils
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.ModelAndView
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * @author 卢浩
 * @date 2020/10/12 4:28 下午
 */
@Component
class AuthenticationInterceptor: HandlerInterceptor {
    private val log: Logger = LoggerFactory.getLogger("Authentication")
    @Autowired
    lateinit var userDao: UserDao

    @Autowired
    lateinit var redisManager: RedisManager

    override fun postHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any, modelAndView: ModelAndView?) {

    }

    override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?) {

    }

    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        log.info("接收到请求")

        println("接收到请求")

        val token = request.getHeader("Authentication")
        if (handler !is HandlerMethod){
            return true
        }

        val handlerMethod = handler as HandlerMethod
        val method = handlerMethod.method
        //判断是不是有PassToken 如果有的话就跳过认证
        if (method.isAnnotationPresent(PassToken::class.java)){
            val passToken = method.getAnnotation(PassToken::class.java)
            if (passToken.required){
                return true
            }
        }

        if (method.isAnnotationPresent(UserLoginToken::class.java)){
            val userLoginToken = method.getAnnotation(UserLoginToken::class.java)
            if (userLoginToken.required){
                if (StringUtils.isEmpty(token)){
                    throw RuntimeException("无Token, 请重新登录")
                }

                val verifier = JWT.require(Algorithm.HMAC256(Constants.Token_Secret_Key)).build()
                try {
                    verifier.verify(token)
                } catch (e: JWTVerificationException) {
                    throw RuntimeException("401")
                }

                var userId = 0
                try {
                    userId = JWT.decode(token).audience[0].toInt()
                } catch (e: JWTDecodeException) {
                    throw RuntimeException("401")
                }


                val user = redisManager.getObjByToken(token, UserVo::class.java) ?: throw RuntimeException("用户不存在, 请重新登录")

                request.setAttribute("user", user)
                return true
            }
        }
        return true
    }
}


